home *** CD-ROM | disk | FTP | other *** search
- // Libreria de subrrutinas : GRAFICOS.H
- // Esta es una libreria de tratamiento gráfico encontrada en el libro
- // Geometría fractal. Algoritmica y representacion- Hay que destacar que no
- // necesita del BGI para realizar lo que quiere hacer.
- // Por exclusión, los procedimientos de circulo, linea, ...
- // aparecidos en esta librería sólo son útiles en el modo
- // 640x480x16 que entra con la función vga640x480.
- // en los demás modos son imprevisibles, además, hay que poner
- // antes la VGA en modo puntos para que funcione bien.
-
- // (C) Bartolomé Borrás Riera Enero 1994
-
- #ifndef __GRAFICOS_H
- #define __GRAFICOS_H
- #pragma inline
-
- #include <dos.h>
- #include <stdio.h>
- #include <conio.h>
- #include <stdlib.h>
-
- #define ABS(x) ((x)<0?-(x):(x))
-
- //---------------------------------------
- // Definición de las estructuras a seguir
- //---------------------------------------
- typedef struct PALETA {
- unsigned char rojo;
- unsigned char verde;
- unsigned char azul;
- } paleta;
-
- //-------------------------------------------------
- // Declaración de los procedimientos de la librería
- //-------------------------------------------------
- void vga320x200(void);
- void vga640x480(void);
- void punto(int,int,int);
- int lee_punto(int,int);
- void paleta16(int[],int[],int[]);
- void paleta256(paleta *);
- void linea(int,int,int,int,char);
- void linrsg(int,int,int,int,int,int);
- void parar_pantalla(void);
- void activar_pantalla(void);
- int video_mode(void);
- void set_video_mode(int);
-
- //---------------------------------------------
- // Implementación de las rutinas de la librería
- //---------------------------------------------
- void parar_pantalla(void)
- {
- union REGS regs;
- regs.x.ax=0x1201;
- regs.h.bl=0x36;
- int86(0x10,®s,®s);
- }
-
- void activar_pantalla(void)
- {
- union REGS regs;
- regs.x.ax=0x1200;
- regs.h.bl=0x36;
- int86(0x10,®s,®s);
- }
-
- void vga320x200(void)
- {
- union REGS regs;
- regs.x.ax=0x13;
- int86(0x10,®s,®s);
- }
-
- void vga640x480(void)
- {
- union REGS regs;
- regs.x.ax=0x12;
- int86(0x10,®s,®s);
- }
-
- void set_video_mode(int modo)
- {
- union REGS regs;
- regs.x.ax=modo;
- int86(0x10,®s,®s);
- }
-
- void punto(int x,int y,int color)
- {
- union REGS regs;
- regs.h.ah=0x0c;
- regs.h.al=color;
- regs.h.bh=0;
- regs.x.cx=x;
- regs.x.dx=y;
- int86(0x10,®s,®s);
- }
-
-
- // =====================================================================
- // Esta función, pone un punto en la pantalla, lo hace directamente
- // programando el puerto 03CEH que es el de video, y de esta forma se
- // consigue una velocidad asombrosa.
- // IMPORTANTE:
- // Sólo sirve, para el modo de video de 640x480x16Colores, en otros
- // modos de video es imprevisible.
- // Para utilizar esta función hay que estar en modo puntos
- // y al finalizar su utilización hay que ponerse en modo planos
- // Programada grácias a la colaboración de A.Tejada y a Wilfred The
- // Mouse.
- // =====================================================================
- void putpunto(int x,int y,int color)
- {
- asm mov cx,x
- asm mov di,cx
- asm shr di,3
- asm and cx,7
- asm mov ax,8008h
- asm shr ah,cl
-
- asm mov dx,03ceh
- asm out dx,ax
-
- asm mov ax,y
- asm shl ax,2
- asm add ax,y
- asm shl ax,4
- asm add di,ax
- asm mov ax,0a000h
- asm mov es,ax
- asm mov ax,color
- asm test al,es:[di]
- asm mov es:[di],al
- }// end putpunto
-
-
- void modo_puntos(void)
- {
- asm mov dx,03ceh
- asm mov ax,0205h
- asm out dx,ax
- }// end modo_puntos
-
- void modo_planos(void)
- {
- asm mov ax,0005h
- asm mov dx,03ceh
- asm out dx,ax
- }// end modo_planos
-
- int lee_punto(int x, int y)
- {
- union REGS regs;
- regs.h.ah=0x0d;
- regs.h.bh=0;
- regs.x.cx=x;
- regs.x.dx=y;
- int86(0x10,®s,®s);
- return(regs.h.al);
- }// end lee_punto
-
- void paleta16(int rojo[],int verde[],int azul[])
- {
- int i;
- int paleta[16]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
- union REGS regs;
- for(i=0;i<16;i++) {
- regs.h.ah=0x10;
- regs.h.al=0x10;
- regs.x.bx=paleta[i];
- regs.h.dh=rojo[i];
- regs.h.ch=verde[i];
- regs.h.cl=azul[i];
- int86(0x10,®s,®s);
- }// end for
- }// end paleta16
-
- void paleta256(paleta*pal)
- {
- union REGS regs;
- regs.x.ax=0x1012;
- regs.x.bx=0x00;
- regs.x.cx=0xff;
- regs.x.dx=(unsigned int) pal;
- int86(0x10,®s,®s);
- }// end paleta256
-
-
-
- // Ahora utilizamos la función de A.Tejada, y el sistema de RPP para trazar la linea.
- // Esto significa que este algoritmo de linea sólo sirve para el modo 640x480x16 colores
- void SwapInt(int *a, int *b)
- {
- int aux;
-
- aux=*a;
- *a=*b;
- *b=aux;
- }
-
- void linea(int x0, int y0, int x1, int y1, char color)
- {
- int dx, dy, IncrS, IncrN, d, x, y, IncrX, IncrY;
- if (abs(y1-y0) < abs(x1-x0)) {
- if (x0 > x1) {
- SwapInt(&x0,&x1);
- SwapInt(&y0,&y1);
- };
- IncrY = (y1 > y0) ? 1:-1;
- dx=x1-x0;
- dy=abs(y1-y0);
- d=2*dy-dx;
- IncrS=2*dy;
- IncrN=2*(dy-dx);
- x=x0;
- y=y0;
- putpunto(x,y,color);
- while (x < x1) {
- if (d <= 0) {
- d+=IncrS;
- x+=1;
- } else {
- d+=IncrN;
- x+=1;
- y+=IncrY;
- };
- putpunto(x,y,color);
- };
- } /* if (abs(y1-y0) < abs(x1-x0)) */
- else {
- if (y0 > y1) {
- SwapInt(&x1,&x0);
- SwapInt(&y1,&y0);
- }
- IncrX = (x1 > x0) ? 1:-1;
- dy=y1-y0;
- dx=abs(x1-x0);
- d=2*dx-dy;
- IncrS=2*dx;
- IncrN=2*(dx-dy);
- x=x0;
- y=y0;
- putpunto(x,y,color);
- while (y < y1) {
- if (d <= 0) {
- d+=IncrS;
- y+=1;
- } else {
- d+=IncrN;
- y+=1;
- x+=IncrX;
- };
- putpunto(x,y,color);
- };
- };
- }// end linea
-
- void lineag(int x1,int y1,int x2,int y2,int anchura,int color)
- {
- int i,dx,dy,fila,col,final,g,inc1,inc2,tan;
-
- dx=x2-x1;
- dy=y2-y1;
- tan=dx>0;
- if(dy<0)
- tan=!tan;
- if(ABS(dx)>ABS(dy)) {
- if(dx>0) {
- col=x1;
- fila=y1;
- final=x2;
- } else {
- col=x2;
- fila=y2;
- final=x1;
- }// end if
- inc1=2*ABS(dy);
- g=inc1-ABS(dx);
- inc2=2*(ABS(dy)-ABS(dx));
- if(tan) {
- while(col <=final) {
- for(i=-anchura/2;i<anchura/2;i++)
- putpunto(col,fila+i,color);
- col++;
- if(g>=0) {
- fila++;
- g+=inc2;
- } else
- g+=inc1;
- }// end while
- } else {
- while(col<=final) {
- for(i=-anchura/2;i<anchura/2;i++)
- putpunto(col,fila+i,color);
- col++;
- if(g>0) {
- fila--;
- g+=inc2;
- } else
- g+=inc1;
- }// end while
- }// end if
- } else {
- if(dy>0) {
- col=x1;
- fila=y1;
- final=y2;
- } else {
- col=x2;
- fila=y2;
- final=y1;
- }// end if
- inc1=2*ABS(dx);
- g=inc1-ABS(dy);
- inc2=2*(ABS(dx)-ABS(dy));
- if(tan) {
- while(fila<=final) {
- for(i=-anchura/2;i<anchura/2;i++)
- putpunto(col+i,fila,color);
- fila++;
- if(g>=0) {
- col++;
- g+=inc2;
- } else
- g+=inc1;
- }// end while
- } else {
- while(fila<=final) {
- for(i=-anchura/2;i<anchura/2;i++)
- putpunto(col+i,fila,color);
- fila++;
- if(g>0) {
- col--;
- g+=inc2;
- } else
- g+=inc1;
- }// end while
- }// end if
- }// end if
- }// end lineag
-
- // En estos momentos, voy a utilizar el algoritmo de Computer Graphics para
- // trazar círculos.
- void p_circ(int x0, int y0,int x, int y, char color)
- {
- putpunto(x0+x,y0+y,color);
- putpunto(x0+x,y0-y,color);
- putpunto(x0-x,y0+y,color);
- putpunto(x0-x,y0-y,color);
- putpunto(x0+y,y0+x,color);
- putpunto(x0+y,y0-x,color);
- putpunto(x0-y,y0+x,color);
- putpunto(x0-y,y0-x,color);
- }// end p_circ
-
- void circulo(int x0,int y0,int radio,char color)
- {
- int x=0,y=radio,d,deltaE=3, deltaSE;
- d= 1-radio;
- deltaSE=-2 * radio +5;
- p_circ(x0,y0,x,y,color);
-
- while (y>x) {
- if (d<0) {
- d += deltaE;
- deltaE += 2;
- deltaSE += 2;
- x++;
- } else {
- d += deltaSE;
- deltaE += 2;
- deltaSE += 4;
- x++;
- y--;
- }// end if
- p_circ(x0,y0,x,y,color);
- }// end while
- }// end circulo
-
-
- int video_mode(void)
- {
- union REGS r;
- r.h.ah = 15;
- return ( int86(0x10, &r, &r) & 255 );
- }
-
- int main(int argc,char *argv[])
- {
- int incx,incy,x=100,y=100,radio,color=0,modo;
- if(argc != 4) {
- puts("\n Sintaxis: GRAFICOS Coord X, Coord Y, Radio \n");
- exit(1);
- }// end if
- incx = atoi(argv[1]);
- incy = atoi(argv[2]);
- radio = atoi(argv[3]);
-
- modo = video_mode();
- vga640x480();
- modo_puntos();
- while (x<540) {
- while (y<380) {
- circulo(x,y,radio,color);
- linea(x-radio,y,x+radio,y,color);
- linea(x,y-radio,x,y+radio,color);
- y+= incy;
- color = ++color %16;
- }// end while
- y=100;
- x +=incx;
- color= ++color % 16;
- }// end while
- modo_planos();
- getch();
- set_video_mode(modo);
- return(0);
- }
- #endif
-